package com.tarena.lbs.marketing.web.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.tarena.lbs.attach.api.AttachApi;
import com.tarena.lbs.base.common.utils.Asserts;
import com.tarena.lbs.base.protocol.exception.BusinessException;
import com.tarena.lbs.base.protocol.pager.PageResult;
import com.tarena.lbs.basic.api.BasicApi;
import com.tarena.lbs.common.passport.principle.UserPrinciple;
import com.tarena.lbs.marketing.web.repository.ActivityRepository;
import com.tarena.lbs.marketing.web.utils.AuthenticationContextUtils;
import com.tarena.lbs.pojo.attach.dto.AttachDTO;
import com.tarena.lbs.pojo.attach.param.PicUpdateParam;
import com.tarena.lbs.pojo.attach.query.AttachQuery;
import com.tarena.lbs.pojo.basic.dto.AdminDTO;
import com.tarena.lbs.pojo.marketing.param.ActivityParam;
import com.tarena.lbs.pojo.marketing.po.ActivityPO;
import com.tarena.lbs.pojo.marketing.query.ActivityQuery;
import com.tarena.lbs.pojo.marketing.vo.ActivityVO;
import com.tarena.lbs.pojo.marketing.vo.CouponVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ActivityService {
    @Autowired
    private ActivityRepository activityRepository;
    //dubbo reference注入
    @DubboReference
    private BasicApi basicApi;

    public PageResult<ActivityVO> pageList(ActivityQuery query) throws BusinessException {
        //1.拿到登录用户的userId
        Integer adminId=getUserId();
        //2.获取登录账号的商家id
        Integer businessId=checkAndGetBusinessId(adminId);
        //3.查询当前businessId下的所有活动列表
        List<ActivityPO> pos= getActivitiesByBusinessId(businessId);
        //4.封装 假的分页对象
        return assemblePageResult(query,pos);
    }

    private List<ActivityPO> getActivitiesByBusinessId(Integer businessId) {
        QueryWrapper<ActivityPO> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("business_id",businessId);
        return activityRepository.list(queryWrapper);
    }

    private PageResult<ActivityVO> assemblePageResult(ActivityQuery query, List<ActivityPO> pos) {
        //pageNo pageSize total
        PageResult<ActivityVO> voPage=
                new PageResult<>(query.getPageSize(),query.getPageNo());
        voPage.setTotal(100l);
        //单独封装po
        if (pos!=null&& pos.size()>0){
            voPage.setObjects(pos.stream().map(po->{
                ActivityVO vo=new ActivityVO();
                BeanUtils.copyProperties(po,vo);
                return vo;
            }).collect(Collectors.toList()));
        }
        return voPage;
    }

    private Integer checkAndGetBusinessId(Integer adminId) throws BusinessException {
        //设计dubbo调用接口
        //远程调用 查询adminDto 断言空 返回businessId
        log.info("marketing调用basic,adminId:{}",adminId);
        AdminDTO adminDTO = basicApi.getAdminDetail(adminId);
        Asserts.isTrue(adminDTO==null,new BusinessException("-2","商家信息获取失败"));
        log.info("marketing调用basic,adminId:{},adminDTO:{}",adminId,adminDTO);
        return adminDTO.getBusinessId();
    }

    private Integer getUserId() throws BusinessException {
        UserPrinciple userPrinciple = AuthenticationContextUtils.get();
        Asserts.isTrue(userPrinciple==null,new BusinessException("-2","认证解析失败"));
        return userPrinciple.getId();
    }

    public void save(ActivityParam param) throws BusinessException {
        //1.拿到用户身份 id
        Integer adminId = getUserId();
        //2.远程调用获取businessId
        Integer businessId = checkAndGetBusinessId(adminId);
        //3.封装po 补充属性新增到数据库
        ActivityPO po=assembleActivityPO(businessId,param);
        activityRepository.save(po);
        //4.远程调用绑定图片 businessType=700 使用图片id
        bindPictures(param,po.getId());
    }
    @DubboReference
    private AttachApi attachApi;
    private void bindPictures(ActivityParam param, Integer id) {
        //将param里携带的imgIds解析成数组 封装List<PicUpdateParam>
        String[] imgIds = param.getImgIds().split(",");
        List<PicUpdateParam> params=null;
        //imgIds非空的时候 创建绑定图片参数
        if(imgIds!=null&&imgIds.length>0){
            params=
                Arrays.stream(imgIds).map(imgId->{
                    PicUpdateParam picParam=new PicUpdateParam();
                    picParam.setBusinessType(700);
                    picParam.setId(Integer.valueOf(imgId));
                    picParam.setBusinessId(id);
                    return picParam;
                }).collect(Collectors.toList());
        }
        //如果params没有值
        if (params==null&&params.size()==0){
            log.error("图片参数封装有问题,入参imgIds:{}",param.getImgIds());
            return;
        }
        attachApi.batchUpdateBusiness(params);
    }

    private ActivityPO assembleActivityPO(Integer businessId, ActivityParam param) {
        ActivityPO po=new ActivityPO();
        BeanUtils.copyProperties(param,po);
        //1.装配businessId
        po.setBusinessId(businessId);
        //2.活动状态 0待开始 1已开始 2已停止 status  管理状态 0启用 1禁用 enableStatus
        po.setStatus(0);
        po.setEnableStatus(0);
        //3.创建时间和修改时间
        po.setCreateAt(new Date());
        po.setUpdateAt(new Date());
        //4.活动开始时间和结束时间 转化一下
        try {
            Date startDate=DateUtils.parseDate(param.getStartDate(), "yyyy-MM-dd HH:mm:ss");
            Date endDate=DateUtils.parseDate(param.getEndDate(), "yyyy-MM-dd HH:mm:ss");
            po.setStartDate(startDate);
            po.setEndDate(endDate);
        }catch (Exception e){
            log.error("入参时间转化出现异常",e);
        }
        //5.保证非空 活动简历类型 优惠券0 积分1
        po.setRewardType(0);
        log.info("封装完成的活动对象:{}",po);
        return po;
    }

    public boolean activityIsVisible(Integer userId, Integer activityId) {
        //1.使用活动id 获取活动详情 拿到targetConsumer
        ActivityPO po = activityRepository.getById(activityId);
        Integer targetGroupId=Integer.valueOf(po.getTargetCustomer());
        //2.调用basic 传递userId 和 businessId 获取用户所属的该商家下的所有人群
        List<Integer> userGroupIds = basicApi.getUserGroupIds(userId, po.getBusinessId());
        //3.判断basic的返回值当中是否存在targetGroupId
        if (userGroupIds!=null){
            return userGroupIds.contains(targetGroupId);
        }else{
            return false;
        }
    }

    public ActivityVO detail(Integer id) {
        ActivityPO po = activityRepository.getById(id);
        if (po!=null){
            ActivityVO vo=new ActivityVO();
            BeanUtils.copyProperties(po,vo);
            //调用一个 图片 查询当前业务绑定的数据 businessType=700 businessId=id
            List<String> imgUrls=getActivityUrls(700,id);
            vo.setImgPics(imgUrls);
            return vo;
        }
        return null;
    }
    @Value("${url.prefix}")
    private String urlPrefix;
    private List<String> getActivityUrls(Integer bizType, Integer bizId) {
        log.info("读取当前环境urlPrefix:{}",urlPrefix);
        //attachApi.batchUpdateBusiness();//更新绑定图片方法
        AttachQuery query=new AttachQuery();
        query.setBusinessType(bizType);
        query.setBusinessId(bizId);
        List<AttachDTO> dtos = attachApi.getAttachInfoByParam(query);
        //dtos是服务之间通信数据返回名称 实际上就是po换了个名字
        //拼接每一张图片需要 urlPrefix根据环境 有所不同 fileUuid attach服务给我返回的
        if (dtos!=null&&dtos.size()>0){
            //将所有dtos元素拿出来 获取fileUuid 拼接urlPrefix
            return dtos.stream().map(dto->{
                return urlPrefix+dto.getFileUuid();
            }).collect(Collectors.toList());
        }else{
            return null;
        }
    }

    public List<Integer> getActivitiesStores(Integer businessId) {
        QueryWrapper<ActivityPO> queryWrapper=new QueryWrapper<>();
        //所属商家business_id
        queryWrapper.eq("business_id",businessId);
        //当前系统时间 >startDate 同时 <endDate 可以添加一些状态
        Date now=new Date();
        queryWrapper.ge("end_date",now).le("start_date",now);
        List<ActivityPO> pos = activityRepository.list(queryWrapper);
        //将pos循环遍历 从字段shopId解析
        List<Integer> shopIds=new ArrayList<>();
        if (pos!=null&&pos.size()>0){
            for (ActivityPO po : pos) {
                //拿到一个活动对象 活动绑定了店铺
                String[] split = po.getShopIds().split(",");
                shopIds.addAll(Arrays.stream(split).map(shopId->{
                    return Integer.valueOf(shopId);
                }).collect(Collectors.toList()));
            }
        }
        //考虑到多个活动对象 可能绑定同一个店铺 应该对最终的返回结果做去重
        if (shopIds.size()>0){
            //TODO 留给你 考虑如果店铺的id重复了怎么去重
        }
        return shopIds;
    }

    public List<ActivityPO> getStoreActivities(Integer storeId) {
        //select * from activity where marketing_type=1 and FIND_IN_SET(?,shop_ids);
        return activityRepository.getStoreActivities(storeId);
    }
}
